package com.seven.webhook.model;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.seven.webhook.model.bean.alertBean.Annotations;
import com.seven.webhook.model.bean.alertBean.Labels;
import com.seven.webhook.model.bean.alertBean.Rule;
import com.seven.webhook.model.bean.alertmanager.Alerts;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;

import java.io.Serializable;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Data
@TableName("monitor_rule")
@EqualsAndHashCode(callSuper = false)
public class MonitorRule implements Serializable {
    @TableId(type = IdType.AUTO)
    private String id;
    @TableField("rule_name")
    private String ruleName;
    @TableField("expr")
    private String expr;
    @TableField("for_time")
    private String forTime;
    @TableField("severity")
    private String severity;
    @TableField("description")
    private String description;
    @TableField("summary")
    private String summary;
    @TableField("monitor_group_id")
    private String monitorGroupId;
    @TableField("is_alert")
    private Boolean isAlert;
    private String instance;


    private static String UTC_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    private static String SIMPLE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public String getSubjectInfo(@NonNull Alerts alerts) {
        String summary = this.summary;//Instance $labels.instance CPU usgae high
        String replace = summary
                .replace("$labels.instance", alerts.getLabels().getInstance() == null
                        ? "" : alerts.getLabels().getInstance())
                .replace("$labels.alertname", alerts.getLabels().getAlertname() == null
                        ? "" : alerts.getLabels().getAlertname())
                .replace("$labels.severity", alerts.getLabels().getSeverity() == null
                        ? "" : alerts.getLabels().getSeverity());
        return replace;
    }

    // TODO: 2020/11/12 解析并返回邮件信息
    public String getSimpleContextInfo(@NonNull Alerts alerts) {
        String description = this.description;//$labels.instance CPU usage above 85% (current value: $value)
        String replace = "时间：" + DateUtil.format(new Date(), SIMPLE_FORMAT) + "\n" + description
                .replace("$labels.instance", alerts.getLabels().getInstance() == null
                        ? "" : alerts.getLabels().getInstance())
                .replace("$value", alerts.getValue().toString() == null
                        ? "" : alerts.getValue().toString());
        return replace;
    }

    /**
     * 将 forTime 转换为 时间戳
     */
    public Long forTime2Long() {
        if (forTime == null) return null;
        //获取时间单位
        String timeUnit = forTime.substring(forTime.length() - 1);
        //获取时间
        String time = forTime.substring(0, forTime.length() - 1);
        return strTimeUnitParse(Long.valueOf(time), timeUnit);
    }

    /**
     * 时间戳转换
     * ms -毫秒
     * s -秒
     * m - 分钟
     * h - 小时
     * d -天-假设一天总是24小时
     * w -周-假设一周始终为7天
     * y -年-假设一年总是365天
     */
    private Long strTimeUnitParse(Long time, @NonNull String timeUnit) {
        switch (timeUnit) {
            case "ms":
                return TimeUnit.MILLISECONDS.toMillis(time);
            case "s":
                return TimeUnit.SECONDS.toMillis(time);
            case "m":
                return TimeUnit.MINUTES.toMillis(time);
            case "h":
                return TimeUnit.HOURS.toMillis(time);
            case "d":
                return TimeUnit.DAYS.toMillis(time);
            case "w":
                return TimeUnit.DAYS.toMillis(time * 7);
            case "y":
                return TimeUnit.DAYS.toMillis(time * 365);
            default:
                throw new RuntimeException("未知时间单位：" + timeUnit);
        }
    }

    /**
     * 将rule 转换为 MonitorRule
     *
     * @return MonitorRule
     */
    public static MonitorRule formatByRule(Rule rule) {
        MonitorRule monitorRule = new MonitorRule();
        BeanUtil.copyProperties(rule, monitorRule);
        monitorRule.setRuleName(rule.getAlert());
        monitorRule.setSeverity(rule.getLabels() == null ? "" : rule.getLabels().getSeverity());
        monitorRule.setDescription(rule.getAnnotations() == null ? "" : rule.getAnnotations().getDescription());
        monitorRule.setSummary(rule.getAnnotations() == null ? "" : rule.getAnnotations().getSummary());
        return monitorRule;
    }

    public Rule parseRule() {
        Rule rule = new Rule();
        Labels labels = new Labels();
        labels.setSeverity(this.severity);
        Annotations annotations = new Annotations();
        annotations.setDescription(this.description);
        annotations.setSummary(this.description);
        rule.setAlert(this.ruleName);
        rule.setExpr(expr);
        rule.setForTime(this.forTime);
        rule.setLabels(labels);
        rule.setAnnotations(annotations);
        return rule;
    }
}
